<template>
  <li class="w-tree-li">
    <div
      :class="`w-tree-li-icon ${
        treeData.expand ? 'w-tree-li-open' : 'w-tree-li-close'
      } 
      ${
        treeData[wChildren] && treeData[wChildren].length === 0
          ? 'w-tree-li-disabled'
          : ''
      }`"
      @click="handleExpand"
    >
      <template v-if="treeData[wChildren]">
        <slot name="showIcon"></slot>
      </template>
    </div>
    <div class="w-tree-li-title">
      <component :is="wNode" :tree-data="treeData"></component>
    </div>
    <template v-if="treeData[wChildren] && treeData[wChildren].length > 0">
      <ul v-show="treeData.expand">
        <template v-for="(t, i) in treeData[wChildren]" :key="i">
          <w-tree-node
            :tree-data="t"
            :default-expand="defaultExpand"
            :w-node="wNode"
            :w-key="wKey"
            :w-children="wChildren"
          >
            <template #showIcon><slot name="showIcon"></slot></template>
          </w-tree-node>
        </template>
      </ul>
    </template>
  </li>
</template>
<script lang="ts">
import { defineComponent, PropType, DefineComponent } from "vue";
import { TreeData } from "./type";
export default defineComponent({
  name: "w-tree-node",
  props: {
    treeData: {
      type: Object as PropType<TreeData>,
      required: true,
      default: () => {
        return {};
      },
    },
    /** 需要展开的 节点key */
    defaultExpand: {
      type: Array as PropType<Array<string>>,
      required: false,
      default: () => {
        return [];
      },
    },
    /** 自定义渲染 */
    wNode: {
      required: true,
      type: Object as PropType<DefineComponent>,
    },
    /** 自定义Key 字段 */
    wKey: {
      type: String,
      default: "key",
    },
    /** 自定义children 字段 */
    wChildren: {
      type: String,
      default: "children",
    },
  },
  emits: ["expand"],
  setup: (props, { emit, slots }) => {
    const { treeData, defaultExpand, wKey, wChildren } = props;
    // 添加展开字段
    if (!treeData?.expand) {
      treeData.expand = false;
    }
    // 默认展开
    if (defaultExpand.includes(treeData[wKey])) {
      treeData.expand = true;
    }
    // 外传 展开事件
    const onExpand = (treeData: TreeData) => {
      emit("expand", treeData);
    };
    // 点击展开关闭事件
    const handleExpand = () => {
      if (treeData[wChildren] && treeData[wChildren].length === 0) {
        return;
      }
      treeData.expand = !treeData.expand;
      onExpand(treeData);
    };
    return { handleExpand };
  },
});
</script>

<style lang="less" scoped>
.w-tree-li {
  list-style: none;
  margin: 0;
  padding: 0;
  margin-left: 20px;
  white-space: nowrap;
  font-size: 14px;
  position: relative;
  &-icon {
    display: inline;
    position: absolute;
    left: -22px;
    top: 8px;
    width: 20px;
    height: 20px;
    line-height: 20px;
    transition: -webkit-transform ease 0.3s;
    transition: transform ease 0.3s;
    transition: transform ease 0.3s, -webkit-transform ease 0.3s;
    -webkit-transform-origin: center;
    transform-origin: center;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  &-open {
    -webkit-transform: rotateZ(0deg);
    transform: rotateZ(0deg);
  }
  &-close {
    -webkit-transform: rotateZ(-90deg);
    transform: rotateZ(-90deg);
  }
  &-disabled {
    cursor: not-allowed;
  }
  &-title {
    height: 36px;
    line-height: 36px;
    cursor: pointer;
    color: #bfc7e4;
  }
  ul {
    text-align: left;
    margin: 0;
    padding: 0;
    user-select: none;
    width: 100%;
    list-style: none;
  }
}
</style>
